﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Client.Components.SearchPanelControls
{
    // V 1.0.1 - 2022-10-30 19:02:18
    // 修复BUG -- Text Binding 的 StringFormat 属性, 当 null 值时报错的显示红框。 解决方法: 添加上 TargetNullValue='' 配置, 当 Text设置为 '' 时, 为绑定的数据设置为 null
    //
    // V 1.0.0 - 2021-08-25 17:56:14
    // 重写并整理代码

    /// <summary>
    /// SearchConditionDateTimeArea
    /// </summary>
    public partial class SearchConditionDateTimeArea : SearchConditionBase
    {
        #region [DP] FromTitle

        /// <summary>
        /// FromTitle
        /// </summary>
        public static readonly DependencyProperty FromTitleProperty = DependencyProperty.Register
        (
            name: "FromTitle",
            propertyType: typeof(string),
            ownerType: typeof(SearchConditionDateTimeArea),
            validateValueCallback: null,
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: "从",
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// FromTitle
        /// </summary>
        public string FromTitle
        {
            get { return (string)GetValue(FromTitleProperty); }
            set { SetValue(FromTitleProperty, value); }
        }

        #endregion

        #region [DP] ToTitle

        /// <summary>
        /// ToTitleProperty
        /// </summary>
        public static readonly DependencyProperty ToTitleProperty = DependencyProperty.Register
        (
            name: "ToTitle",
            propertyType: typeof(string),
            ownerType: typeof(SearchConditionDateTimeArea),
            validateValueCallback: null,
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: "至",
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// ToTitleProperty
        /// </summary>
        public string ToTitle
        {
            get { return (string)GetValue(ToTitleProperty); }
            set { SetValue(ToTitleProperty, value); }
        }

        #endregion

        #region [DP] FromDateTime

        /// <summary>
        /// FromDateTime
        /// </summary>
        public static readonly DependencyProperty FromDateTimeProperty = DependencyProperty.Register
        (
            name: "FromDateTime",
            propertyType: typeof(DateTime?),
            ownerType: typeof(SearchConditionDateTimeArea),
            validateValueCallback: null,
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: null,
                flags: FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                propertyChangedCallback: onFromDate_PropertyChangedCallback,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// FromDateTime
        /// </summary>
        public DateTime? FromDateTime
        {
            get { return (DateTime?)GetValue(FromDateTimeProperty); }
            set { SetValue(FromDateTimeProperty, value); }
        }

        /// <summary>
        /// onFromDate_PropertyChangedCallback
        /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        public static void onFromDate_PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is SearchConditionDateTimeArea target)
            {
                if ((DateTime?)e.NewValue > target.ToDateTime && target.ToDateTime.HasValue)
                {
                    if (target.FromDateError != null)
                    {
                        target.FromDateError(d, e);
                    }
                    target.FromDateTime = (DateTime?)e.OldValue;
                }
            }
        }

        #endregion

        #region [DP] ToDateTime

        /// <summary>
        /// ToDateTime
        /// </summary>
        public static readonly DependencyProperty ToDateTimeProperty = DependencyProperty.Register
        (
            name: "ToDateTime",
            propertyType: typeof(DateTime?),
            ownerType: typeof(SearchConditionDateTimeArea),
            validateValueCallback: null,
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: null,
                flags: FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                propertyChangedCallback: onToDate_PropertyChangedCallback,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// ToDateTime
        /// </summary>
        public DateTime? ToDateTime
        {
            get { return (DateTime?)GetValue(ToDateTimeProperty); }
            set { SetValue(ToDateTimeProperty, value); }
        }

        /// <summary>
        /// onToDate_PropertyChangedCallback
        /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        public static void onToDate_PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is SearchConditionDateTimeArea target)
            {
                if ((DateTime?)e.NewValue < target.FromDateTime && target.FromDateTime.HasValue)
                {
                    if (target.ToDateError != null)
                    {
                        target.ToDateError(d, e);
                    }
                    target.ToDateTime = (DateTime?)e.OldValue;
                }
            }
        }

        #endregion

        #region [DP] Max~Min - From~ToDate

        /// <summary>
        /// MinFromDate
        /// </summary>
        public static readonly DependencyProperty MinFromDateProperty = DependencyProperty.Register("MinFromDate", typeof(DateTime?), typeof(SearchConditionDateTimeArea));

        /// <summary>
        /// MinFromDate
        /// </summary>
        public DateTime? MinFromDate
        {
            get { return (DateTime?)GetValue(MinFromDateProperty); }
            set { SetValue(MinFromDateProperty, value); }
        }


        /// <summary>
        /// MaxFromDate
        /// </summary>
        public static readonly DependencyProperty MaxFromDateProperty = DependencyProperty.Register("MaxFromDate", typeof(DateTime?), typeof(SearchConditionDateTimeArea));
        
        /// <summary>
        /// MaxFromDate
        /// </summary>
        public DateTime? MaxFromDate
        {
            get { return (DateTime?)GetValue(MaxFromDateProperty); }
            set { SetValue(MaxFromDateProperty, value); }
        }


        /// <summary>
        /// MinToDate
        /// </summary>
        public static readonly DependencyProperty MinToDateProperty = DependencyProperty.Register("MinToDate", typeof(DateTime?), typeof(SearchConditionDateTimeArea));

        /// <summary>
        /// MinToDate
        /// </summary>
        public DateTime? MinToDate
        {
            get { return (DateTime?)GetValue(MinToDateProperty); }
            set { SetValue(MinToDateProperty, value); }
        }


        /// <summary>
        /// MaxToDate
        /// </summary>
        public static readonly DependencyProperty MaxToDateProperty = DependencyProperty.Register("MaxToDate", typeof(DateTime?), typeof(SearchConditionDateTimeArea));

        /// <summary>
        /// MaxToDate
        /// </summary>
        public DateTime? MaxToDate
        {
            get { return (DateTime?)GetValue(MaxToDateProperty); }
            set { SetValue(MaxToDateProperty, value); }
        }

        #endregion

        #region [DP] TextBoxBackground

        /// <summary>
        /// TextBoxBackground
        /// </summary>
        public static readonly DependencyProperty TextBoxBackgroundProperty = DependencyProperty.Register
        (
            name: "TextBoxBackground",
            propertyType: typeof(System.Windows.Media.Brush),
            ownerType: typeof(SearchConditionDateTimeArea),
            validateValueCallback: null,
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(245, 245, 245)),
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// TextBoxBackground
        /// </summary>
        public System.Windows.Media.Brush TextBoxBackground
        {
            get { return (System.Windows.Media.Brush)GetValue(TextBoxBackgroundProperty); }
            set { SetValue(TextBoxBackgroundProperty, value); }
        }

        #endregion

        #region [DP] Placeholder

        /// <summary>
        /// Placeholder
        /// </summary>
        public static readonly DependencyProperty PlaceholderProperty = DependencyProperty.Register
        (
            name: "Placeholder",
            propertyType: typeof(string),
            ownerType: typeof(SearchConditionDateTimeArea),
            validateValueCallback: null, // new ValidateValueCallback((toValidate) => { return true; }),
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: "yyyy-MM-dd HH:mm:ss.f7",
                // flags: FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// Placeholder
        /// </summary>
        public string Placeholder
        {
            get { return (string)GetValue(PlaceholderProperty); }
            set { SetValue(PlaceholderProperty, value); }
        }

        #endregion

        #region [DP] PlaceholderColor

        /// <summary>
        /// PlaceholderColor
        /// </summary>
        public static readonly DependencyProperty PlaceholderColorProperty = DependencyProperty.Register
        (
            name: "PlaceholderColor",
            propertyType: typeof(System.Windows.Media.Brush),
            ownerType: typeof(SearchConditionDateTimeArea),
            validateValueCallback: null, // new ValidateValueCallback((toValidate) => { return true; }),
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: System.Windows.Media.Brushes.Gray,
                // flags: FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// PlaceholderColor
        /// </summary>
        public System.Windows.Media.Brush PlaceholderColor
        {
            get { return (System.Windows.Media.Brush)GetValue(PlaceholderColorProperty); }
            set { SetValue(PlaceholderColorProperty, value); }
        }

        #endregion

        #region [DP] FromIsReadOnly

        /// <summary>
        /// FromIsReadOnly
        /// </summary>
        public static readonly DependencyProperty FromIsReadOnlyProperty = DependencyProperty.Register
        (
            name: "FromIsReadOnly",
            propertyType: typeof(bool),
            ownerType: typeof(SearchConditionDateTimeArea),
            validateValueCallback: null,
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: false,
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// FromIsReadOnly
        /// </summary>
        public bool FromIsReadOnly
        {
            get { return (bool)GetValue(FromIsReadOnlyProperty); }
            set { SetValue(FromIsReadOnlyProperty, value); }
        }

        #endregion

        #region [DP] ToIsReadOnly

        /// <summary>
        /// ToIsReadOnly
        /// </summary>
        public static readonly DependencyProperty ToIsReadOnlyProperty = DependencyProperty.Register
        (
            name: "ToIsReadOnly",
            propertyType: typeof(bool),
            ownerType: typeof(SearchConditionDateTimeArea),
            validateValueCallback: null, 
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: false,
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// ToIsReadOnly
        /// </summary>
        public bool ToIsReadOnly
        {
            get { return (bool)GetValue(ToIsReadOnlyProperty); }
            set { SetValue(ToIsReadOnlyProperty, value); }
        }

        #endregion

        #region [DP] FromIsEnabled

        /// <summary>
        /// FromIsEnabled
        /// </summary>
        public static readonly DependencyProperty FromIsEnabledProperty = DependencyProperty.Register
        (
            name: "FromIsEnabled",
            propertyType: typeof(bool),
            ownerType: typeof(SearchConditionDateTimeArea),
            validateValueCallback: null, // new ValidateValueCallback((toValidate) => { return true; }),
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: true,
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// FromIsEnabled
        /// </summary>
        public bool FromIsEnabled
        {
            get { return (bool)GetValue(FromIsEnabledProperty); }
            set { SetValue(FromIsEnabledProperty, value); }
        }

        #endregion

        #region [DP] ToIsEnabled

        /// <summary>
        /// ToIsEnabled
        /// </summary>
        public static readonly DependencyProperty ToIsEnabledProperty = DependencyProperty.Register
        (
            name: "ToIsEnabled",
            propertyType: typeof(bool),
            ownerType: typeof(SearchConditionDateTimeArea),
            validateValueCallback: null,
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: true,
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// ToIsEnabled
        /// </summary>
        public bool ToIsEnabled
        {
            get { return (bool)GetValue(ToIsEnabledProperty); }
            set { SetValue(ToIsEnabledProperty, value); }
        }

        #endregion

        /// <summary>
        /// Reset
        /// </summary>
        public override void Reset()
        {
            this.txtFromDateTime.Text = string.Empty;
            this.txtToDateTime.Text = string.Empty;

            this.FromDateTime = null;
            this.ToDateTime = null;
        }

        /// <summary>
        /// SearchConditionDateTimeArea
        /// </summary>
        public SearchConditionDateTimeArea()
        {
            InitializeComponent();
        }

        /// <summary>
        /// FromDateError
        /// </summary>
        public event PropertyChangedCallback FromDateError;

        /// <summary>
        /// ToDateError
        /// </summary>
        public event PropertyChangedCallback ToDateError;
    }
}
